"""
Quoridor student player starter file
 
Author: Adam Oest
        Mike Yachanin
        David Fryer
        Isaiah Cote
Date: July, 2012
"""

# TODO: GENERAL: Get Multiplayer Working.

# Imports the player move class as well as the board size constant
from Model.interface import PlayerMove, BOARD_DIM
from StudentPlayers.TheFightingPenguins.playerData import *
from StudentPlayers.TheFightingPenguins.bfs.bfs import *
from random import *


def init(logger, playerId, numWalls, playerHomes):
    """
        Part 1 - 4
    
        The engine calls this function once at the beginning of the game.
        The student player module uses this function to initialize its data
        structures to the initial game state.

        Parameters
            logger: a reference to the logger object. The player model uses
                logger.write(msg) and logger.error(msg) to log diagnostic
                information.
                
            playerId: this player's number, from 1 to 4
        
            numWalls: the number of walls each player is given initially
            
            playerHomes: An ordered tuple of player locations
                         A location is a 2-element tuple of (row,column).
                         If any player has already been eliminated from
                         the game (rare), there will be a bool False in
                         that player's spot in the tuple instead of a
                         location.
                    
        returns:
            a PlayerData object containing all of this player module's data
    """
    
    # This is where you must initialize all the information in your PlayerData
    # object. It should store things like how many players and initial
    # configuration of the board.
    #
    # Sample code body
    #
    # In the example code body below, the PlayerData class contained in the
    # file playerData.py is just used as an example. Feel free to alter it.
    # Just make sure it contains everything you need.
    playerData = PlayerData(logger, playerId, list(playerHomes), playerHomes[playerId-1][0], playerHomes[playerId-1][1], numWalls, True)
    return playerData

def last_move(playerData, move):
    """
        Parts 1 - 4
    
        The engine calls this function after any player module, including this one,
        makes a valid move in the game.
        
        The engine also calls this function repeatedly at the start of the game if
        there have been some moves specified in the configuration file's PRE_MOVE
        variable.

        The student player module updates its data structure with the information
        about the move.

        Parameters
            playerData: this player's data, originally built by this
                        module in init()
        
            move: the instance of PlayerMove that describes the move just made
        
        returns:
            this player module's updated (playerData) data structure
    """
    
    # Update your playerData object with the latest move.
    # Remember that this code is called even for your own moves.
    
    #TODO: double-check that this works for multiplayer 
    if(not move.move):
        if(move.playerId == playerData.playerId):
            playerData.wallCount-=1
        playerData.add_walls(move.r1,move.r2,move.c1,move.c2)
    else:
        #TODO: this needs to be changed to update ONLY FOR THE PLAYER THAT MOVES
        moveTo=[move.r2,move.c2]
        if(move.playerId == playerData.playerId):
            playerData.playerHistory.append(moveTo)
        else:
            playerData.playerLocations[move.playerId-1]=moveTo
    return playerData

def get_neighbors(playerData, r, c):
    """
        Part 1
    
        This function is used only in part 1 mode. The engine calls it after
        all PRE_MOVEs have been made. (See the config.cfg file.)

        Parameters
            playerData: this player's data, originally built by this
                        module in init()
            r: row coordinate of starting position for this player's piece
            c: column coordinate of starting position for this player's piece
        
        returns:
            a list of coordinate pairs (a list of lists, e.g. [[0,0], [0,2]],
            not a list of tuples) denoting all the reachable neighboring squares
            from the given coordinate. "Neighboring" means exactly one move
            away.
    """
    
    # Use your playerData object to get a list of neighbors
    #DON'T USE THIS. EVER.
    neighbors=[]
    if(r-1>=0):
        neighbors.append([r-1,c])
    if(c-1>=0):
        neighbors.append([r,c-1])
    if(r+1<9):
        neighbors.append([r+1,c])
    if(c+1<9):
        neighbors.append([r,c+1])
    return neighbors

def get_shortest_path(playerData, r1, c1, r2, c2):
    """
        Part 1
    
        This function is only called in part 1 mode. The engine calls it when
        a shortest path is requested by the user via the graphical interface.

        Parameters
            playerData: this player's data, originally built by this
                        module in init()
            r1: row coordinate of starting position
            c1: column coordinate of starting position
            r2: row coordinate of destination position
            c2: column coordinate of destination position
        
        returns:
            a list of coordinates that form the shortest path from the starting
            position to the destination, inclusive. The format is an ordered
            list of coordinate pairs (a list of lists, e.g.,
            [[0,0], [0,1], [1,1]], not a list of tuples).
            If there is no path, an empty list, [], should be returned.
    """
    
    # Use your playerData object to find a shortest path using breadth-first
    # search (BFS).
    # You will probably find the get_neighbors function helpful.
    path = searchBFS(playerData.board[r1][c1],playerData.board[r2][c2],playerData.board)
    if(len(path)<2 or len(path)>9 or path[1] in playerData.playerLocations):
        shortPath=path
        cOrig=c2
        while True:
            if(c2+1<9):
                c2+=1
            else:
                c2=0
            if(c2 == cOrig):
                path=shortPath
                break
            temp=searchBFS(playerData.board[r1][c1],playerData.board[r2][c2],playerData.board)
            if(len(temp)<len(shortPath) or temp!=path):
                if(temp!=path):
                    shortPath=temp
    return path

def move(playerData):
    """
        Parts 2 - 4
    
        The engine calls this function at each moment when it is this
        player's turn to make a move. This function decides what kind of
        move, wall placement or piece move, to make.
        
        Parameters
            playerData: this player's data, originally built by this
                        module in init()
        
        returns:
            the move chosen, in the form of an instance of PlayerMove
    """
    
    # This function is called when it's your turn to move
        
    # Here you'll figure out what kind of move to make and then return that
    # move. We recommend that you don't update your data structures here,
    # but rather in last_move. If you do it here, you'll need a special case
    # check in last_move to make sure you don't update your data structures
    # twice.
        
    # In part 3, any legal move is acceptable. In part 4, you will want to
    # implement a strategy
    
    # Placeholder, fill in these values yourself
    # find shortest path to the other side of the board
    # TODO: This needs to change to accomodate more than one player.
    if playerData.wallCount == 0:
        playerData.movePawn = True
    # gets shortest path
    if(playerData.playerId == 1 or playerData.playerId == 2):
        shortestPath = get_shortest_path(playerData, playerData.getCurLoc()[0], playerData.getCurLoc()[1], playerData.destination, playerData.getCurLoc()[1])
        if playerData.playerId == 1:
            oppPath = get_shortest_path(playerData, playerData.playerLocations[1][0], playerData.playerLocations[1][1], 8, playerData.playerLocations[1][1])
        else:
            oppPath = get_shortest_path(playerData, playerData.playerLocations[0][0], playerData.playerLocations[0][1], 0, playerData.playerLocations[0][1])
    elif(playerData.playerId == 3 or playerData.playerId == 4):
        shortestPath = get_shortest_path(playerData, playerData.getCurLoc()[0], playerData.getCurLoc()[1], playerData.getCurLoc()[0], playerData.destination)
        if playerData.playerId == 3:
            oppPath = get_shortest_path(playerData, playerData.playerLocations[3][0], playerData.playerLocations[3][1], 8, playerData.playerLocations[3][1])
        else:
            oppPath = get_shortest_path(playerData, playerData.playerLocations[2][0], playerData.playerLocations[2][1], 0, playerData.playerLocations[2][1])
        
    # move, checking for collisions
    """
    move=None
    if(len(oppPath)<len(shortestPath) and playerData.wallCount>0):
        move=placeWall(oppPath,playerData, shortestPath)
    else:
        move=movePlayer(shortestPath,oppPath,playerData)
 
    return move
    """
    return placeWall(oppPath,playerData, shortestPath)

def placeWall(opath, playerData, shortestPath):
    """
     Checks to see if the program, has any walls left to place.
    """
    if(playerData.wallCount>0):
        return derpPlace(opath, playerData, shortestPath)
    else:
        return movePlayer(shortestPath,opath,playerData)

def notTerribleWallPlace(shortestPath, opath, playerData):
    """
    If the wall placement strategy used by derpPlace becomes blocked by an opposing wall then the program switches to wall placements 
    generated by notTerribleWallPlace.  Which places walls based on our shortestPath VS our opponent's shortestPath.
    
    Parameters
            playerData: this player's data, originally built by this module in init()
            opath: our opponent's shortest path based on a BFS search
            shortestPath: our AI's shortest path based on a BFS search
            
    returns
            A wall placement using a call of either a vertical wall or a horizontal wall. 
    
    """
    if(len(opath)<=len(shortestPath) and playerData.wallCount>0 and len(opath)>0):
        if opath[0][0] != opath[1][0]:
            return placeHorizontalWall(opath, playerData, shortestPath)
        else:
            return placeVerticalWall(opath, playerData, shortestPath)  
    else:
        return movePlayer(shortestPath,opath,playerData)

def checkEvilPlan(playerData):
    """
    Checks to see if the strategy utilized by derpPalce is or is not countered by a wall placement.
    
    Parameters
            playerData: this player's data, originally built by this
                        module in init()
    returns:  True if the strategy is blocked, False if it is not
    
    """
    if playerData.playerId == 1:
        for i in range(2,9):
            temp = WallData(i,0,i,2)
            for wall in playerData.walls:
                if temp.start == wall.start and temp.end == wall.end:
                    playerData.isBlocked = True
            if i % 2 == 0:
                temp = WallData(1,i,3,i)
                for wall in playerData.walls:
                    if temp.start == wall.start and temp.end == wall.end:
                        playerData.isBlocked = True
        for i in range(1,5):
            temp = WallData(7,i,9,i)
            for wall in playerData.walls:
                if temp.start == wall.start and temp.end == wall.end:
                    playerData.isBlocked = True
        for i in range(2,7):
            if i % 2 == 0:
                temp = WallData(7,i,7,i+2)
                for wall in playerData.walls:
                    if temp.start == wall.start and temp.end == wall.end:
                        playerData.isBlocked = True

    else:
        for i in range(2,9):
            temp = WallData(i,0,i,2)
            for wall in playerData.walls:
                if temp.start == wall.start and temp.end == wall.end:
                    playerData.isBlocked = True
            if i % 2 == 0:
                temp = WallData(1,i,3,i)
                for wall in playerData.walls:
                    if temp.start == wall.start and temp.end == wall.end:
                        playerData.isBlocked = True
        for i in range(1,5):
            temp = WallData(0,i,2,i)
            for wall in playerData.walls:
                if temp.start == wall.start and temp.end == wall.end:
                    playerData.isBlocked = True
        for i in range(2,7):
            if i % 2 == 0:
                temp = WallData(2,i,2,i+2)
                for wall in playerData.walls:
                    if temp.start == wall.start and temp.end == wall.end:
                        playerData.isBlocked = True
                        
def derpPlace(opath, playerData, shortestPath):
    """
    derpPlace is the primary wall placement strategy for our AI, it places walls in a series of locations based on whether we are player1
    or player2 based on the present playerData, our opponents path(opath), and our shortestPath.  
    
    Parameters
            playerData: this player's data, originally built by this module in init()
            opath: our opponent's shortest path based on a BFS search
            shortestPath: our AI's shortest path based on a BFS search
            
    returns
        A call of playerMove to make a hard coded wall placement, or a call of notTerribleWallPlace.
    """
    if playerData.numPlayers != 4 and not playerData.isBlocked:
        checkEvilPlan(playerData)
        if playerData.playerId == 2 and not playerData.isBlocked:
            if not wallData.checkCollision(6, 1, 8, 1, playerData):
                return PlayerMove(playerData.playerId, False, 6, 1, 8, 1)
            if not wallData.checkCollision(4, 1, 6, 1, playerData):
                return PlayerMove(playerData.playerId, False, 4, 1, 6, 1)
            if not wallData.checkCollision(2, 1, 4, 1, playerData):
                return PlayerMove(playerData.playerId, False, 2, 1, 4, 1)
            if not wallData.checkCollision(2, 1, 2, 3, playerData):
                return PlayerMove(playerData.playerId, False, 2, 1, 2, 3)
            if not wallData.checkCollision(2, 5, 2, 7, playerData):
                return PlayerMove(playerData.playerId, False, 2, 5, 2, 7)
            if not wallData.checkCollision(2, 3, 2, 5, playerData):
                return PlayerMove(playerData.playerId, False, 2, 3, 2, 5)
            if not wallData.checkCollision(2, 7, 2, 9, playerData):
                return PlayerMove(playerData.playerId, False, 2, 7, 2, 9)
            if playerData.firstMove:
                playerData.firstMove = False
                if([1,4] in playerData.board[playerData.getCurLoc()[0]][playerData.getCurLoc()[1]].neighbors):
                    return PlayerMove(playerData.playerId, True, 0, 4, 1, 4)
        elif not playerData.isBlocked:
            if not wallData.checkCollision(1, 1, 3, 1, playerData):
                return PlayerMove(playerData.playerId, False, 1, 1, 3, 1)
            if not wallData.checkCollision(3, 1, 5, 1, playerData):
                return PlayerMove(playerData.playerId, False, 3, 1, 5, 1)
            if not wallData.checkCollision(5, 1, 7, 1, playerData):
                return PlayerMove(playerData.playerId, False, 5, 1, 7, 1)
            if not wallData.checkCollision(7, 1, 7, 3, playerData):
                return PlayerMove(playerData.playerId, False, 7, 1, 7, 3)
            if not wallData.checkCollision(7, 5, 7, 7, playerData):
                return PlayerMove(playerData.playerId, False, 7, 5, 7, 7)
            if not wallData.checkCollision(7, 7, 7, 9, playerData):
                return PlayerMove(playerData.playerId, False, 7, 7, 7, 9)
            if not wallData.checkCollision(7, 3, 7, 5, playerData):
                return PlayerMove(playerData.playerId, False, 7, 3, 7, 5)
            if playerData.firstMove:
                playerData.firstMove = False
                if([7,4] in playerData.board[playerData.getCurLoc()[0]][playerData.getCurLoc()[1]].neighbors):
                    return PlayerMove(playerData.playerId, True, 8, 4, 7, 4)
    return notTerribleWallPlace(shortestPath, opath, playerData)

def placeHorizontalWall(opath, playerData, shortestPath):
    """
    placeHorizonatalWall is called by notTerribleWallPlace, when the program decides to place a horizontal wall and does so based on
    player positions and paths.
    
    Parameters
            playerData: this player's data, originally built by this module in init()
            opath: our opponent's shortest path based on a BFS search
            shortestPath: our AI's shortest path based on a BFS search
            
    returns
            A valid wall placement move that is in the horizontal position.
     
    """
    if playerData.playerId == 1:
        posx = opath[1][0]
        posy = opath[1][1]
    else:
        posx = opath[1][0] + 1
        posy = opath[1][1]
    if opath[0][0] < posx:
        if opath[0][1] > 5:
            if not wallData.checkCollision(posx, posy-1, posx, posy+1, playerData):
                return PlayerMove(playerData.playerId, False, posx, posy-1, posx, posy+1)
            
            elif not wallData.checkCollision(posx, posy, posx, posy+2, playerData):
                return PlayerMove(playerData.playerId, False, posx, posy, posx, posy+2)

        else:
            if not wallData.checkCollision(posx, posy, posx, posy+2, playerData):
                return PlayerMove(playerData.playerId, False, posx, posy, posx, posy+2)
            
            elif not wallData.checkCollision(posx, posy-1, posx, posy+1, playerData):
                return PlayerMove(playerData.playerId, False, posx, posy-1, posx, posy+1)
    
    else:
        if opath[0][1] < 5:
            if not wallData.checkCollision(posx, posy-1, posx, posy+1, playerData):
                return PlayerMove(playerData.playerId, False, posx, posy-1, posx, posy+1)
            
            elif not wallData.checkCollision(posx, posy, posx, posy+2, playerData):
                return PlayerMove(playerData.playerId, False, posx, posy, posx, posy+2)
    
        else:
            if not wallData.checkCollision(posx, posy, posx, posy+2, playerData):
                return PlayerMove(playerData.playerId, False, posx, posy, posx, posy+2)
            
            elif not wallData.checkCollision(posx, posy-1, posx, posy+1, playerData):
                return PlayerMove(playerData.playerId, False, posx, posy-1, posx, posy+1)
                
    return movePlayer(shortestPath, opath, playerData)

def placeVerticalWall(opath, playerData, shortestPath):
    """
    placeVerticalWall is called by notTerribleWallPlace, when the program decides to place a vertical wall and does so based on
    player positions and paths.
    
    Parameters
            playerData: this player's data, originally built by this module in init()
            opath: our opponent's shortest path based on a BFS search
            shortestPath: our AI's shortest path based on a BFS search
            
    returns
            A valid wall placement move that is in the horizontal position.
     
    """
    #if playerData.playerId == 1:
    posx = opath[1][0]
    posy = opath[1][1]
    """
    else:
        posx = opath[1][0] + 1
        posy = opath[1][1]
    """
    if opath[0][1] < posy:
       if not playerData.wallAt(posx, posy+1, posx+2, posy+1):
           if not wallData.checkCollision(posx, posy+2, posx+2, posy+2, playerData):
               return PlayerMove(playerData.playerId, False, posx, posy+2, posx+2, posy+2)
       
           elif not wallData.checkCollision(posx, posy+1, posx+2, posy+1, playerData):
               return PlayerMove(playerData.playerId, False, posx, posy+1, posx+2, posy+1)
       
       if not playerData.wallAt(posx-1, posy+1, posx+1, posy+1):
           if not wallData.checkCollision(posx-1, posy+2, posx+1, posy+2, playerData):
               return PlayerMove(playerData.playerId, False, posx-1, posy+2, posx+1, posy+2)
       
           elif not wallData.checkCollision(posx-1, posy+1, posx+1, posy+1, playerData):
               return PlayerMove(playerData.playerId, False, posx-1, posy+1, posx+1, posy+1)    

    else:
       if not playerData.wallAt(posx, posy, posx+2, posy):
           if not wallData.checkCollision(posx, posy-1, posx+2, posy-1, playerData):
               return PlayerMove(playerData.playerId, False, posx, posy-1, posx+2, posy-1)
       
           elif not wallData.checkCollision(posx, posy, posx+2, posy, playerData):
               return PlayerMove(playerData.playerId, False, posx, posy, posx+2, posy)
       
       if not playerData.wallAt(posx-1, posy, posx+1, posy):
          if not wallData.checkCollision(posx-1, posy-1, posx+1, posy-1, playerData):
              return PlayerMove(playerData.playerId, False, posx-1, posy-1, posx+1, posy-1)
       
          elif not wallData.checkCollision(posx-1, posy, posx+1, posy, playerData):
              return PlayerMove(playerData.playerId, False, posx-1, posy, posx+1, posy)
       
    return movePlayer(shortestPath, opath, playerData)

def movePlayer(shortestPath,oPath,playerData):
    """
    movePlayer makes a valid pawn move on the board based on the locations of walls, other players, our shortestPath, and our opponent's 
    shortestPath.
    
    Parameters
            playerData: this player's data, originally built by this module in init()
            opath: our opponent's shortest path based on a BFS search
            shortestPath: our AI's shortest path based on a BFS search
    
    returns
            A valid true playerMove(the pawn moves)
    """
    move=None
    while(len(shortestPath)<2):
        if(playerData.playerId == 1 or playerData.playerId == 2):
            tempC=playerData.getCurLoc()
            if(tempC[1]+1>8):
                tempcC[1]-=1
                shortestPath = get_shortest_path(playerData, playerData.getCurLoc()[0], playerData.getCurLoc()[1], playerData.destination, tempC[1])
            else:
                tempC[1]+=1
                shortestPath = get_shortest_path(playerData, playerData.getCurLoc()[0], playerData.getCurLoc()[1], playerData.destination, tempC[1])
        elif(playerData.playerId == 3 or playerData.playerId == 4):
            shortestPath = get_shortest_path(playerData, playerData.getCurLoc()[0], playerData.getCurLoc()[1], playerData.getCurLoc()[0], playerData.destination)
    if(shortestPath[1] not in playerData.playerLocations):
        move = PlayerMove(playerData.playerId, True, shortestPath[0][0], shortestPath[0][1], shortestPath[1][0], shortestPath[1][1])  # r2 and c2 need to be set
    else:
        opp_neighbors = playerData.board[shortestPath[1][0]][shortestPath[1][1]].getNeighbors()
        if(len(opp_neighbors)<=3 and shortestPath[2] in opp_neighbors):
            if(shortestPath[2] not in playerData.playerLocations):
                curLoc=playerData.getCurLoc()
                #moves diagonally iff only (productive) move
                if(curLoc[0]==shortestPath[1][0]): #sideways movement
                    if(curLoc[1]+1==shortestPath[1][1] and [shortestPath[1][0], shortestPath[1][1]+1] in opp_neighbors): 
                        move = PlayerMove(playerData.playerId, True, curLoc[0], curLoc[1], shortestPath[1][0], shortestPath[1][1]+1)
                    elif(curLoc[1]-1==shortestPath[1][1] and [shortestPath[1][0], shortestPath[1][1]-1] in opp_neighbors):
                        move = PlayerMove(playerData.playerId, True, curLoc[0], curLoc[1], shortestPath[1][0], shortestPath[1][1]-1)
                    else:
                        move = PlayerMove(playerData.playerId, True, shortestPath[0][0], shortestPath[0][1], shortestPath[2][0], shortestPath[2][1])
                elif(curLoc[1]==shortestPath[1][1]): #vertical movement
                    if(curLoc[0]+1==shortestPath[1][0] and [shortestPath[1][0]+1, shortestPath[1][1]] in opp_neighbors): 
                        move = PlayerMove(playerData.playerId, True, curLoc[0], curLoc[1], shortestPath[1][0]+1, shortestPath[1][1])
                    elif(curLoc[0]-1==shortestPath[1][0] and [shortestPath[1][0]-1, shortestPath[1][1]] in opp_neighbors):
                        move = PlayerMove(playerData.playerId, True, curLoc[0], curLoc[1], shortestPath[1][0]-1, shortestPath[1][1])    
                    else:
                        move = PlayerMove(playerData.playerId, True, shortestPath[0][0], shortestPath[0][1], shortestPath[2][0], shortestPath[2][1])
            else:
                prevLoc=playerData.playerHistory[len(playerData.playerHistory)-2]
                curLoc=playerData.playerHistory[len(playerData.playerHistory)-1]
                if(prevLoc not in playerData.playerLocations):
                    move = PlayerMove(playerData.playerId, True, curLoc[0], curLoc[1], prevLoc[0], prevLoc[1])
                else:
                    if(playerData.wallCount>0):
                        move = placeWall(oPath,playerData)
                    else:
                        #pass
                        move = PlayerMove(playerData.playerId, True, curLoc[0], curLoc[1], curLoc[0], curLoc[1])
        else:
            curLoc=playerData.getCurLoc()
            if(curLoc[0]==shortestPath[1][0]):
                if(curLoc[1]+1==shortestPath[1][1] and [shortestPath[1][0], shortestPath[1][1]+1] in playerData.board[shortestPath[1][0]][shortestPath[1][1]].getNeighbors()): 
                    move = PlayerMove(playerData.playerId, True, curLoc[0], curLoc[1], shortestPath[1][0], shortestPath[1][1]+1)
                elif(curLoc[1]-1==shortestPath[1][1] and [shortestPath[1][0], shortestPath[1][1]-1] in playerData.board[shortestPath[1][0]][shortestPath[1][1]].getNeighbors()):
                    move = PlayerMove(playerData.playerId, True, curLoc[0], curLoc[1], shortestPath[1][0], shortestPath[1][1]-1)
            elif(curLoc[1]==shortestPath[1][1]):
                if(curLoc[0]+1==shortestPath[1][0] and [shortestPath[1][0]+1, shortestPath[1][1]] in playerData.board[shortestPath[1][0]][shortestPath[1][1]].getNeighbors()): 
                    move = PlayerMove(playerData.playerId, True, curLoc[0], curLoc[1], shortestPath[1][0]+1, shortestPath[1][1])
                elif(curLoc[0]-1==shortestPath[1][0] and [shortestPath[1][0]-1, shortestPath[1][1]] in playerData.board[shortestPath[1][0]][shortestPath[1][1]].getNeighbors()):
                    move = PlayerMove(playerData.playerId, True, curLoc[0], curLoc[1], shortestPath[1][0]-1, shortestPath[1][1])
    return move

def player_invalidated(playerData, playerId):
    """
        Part 3 - 4
    
        The engine calls this function when another player has made
        an invalid move or has raised an exception ("crashed").
        
        Parameters
            playerData: this player's data, originally built by this
                        module in init()
            playerId: the ID of the player being invalidated
        
        returns:
            this player's updated playerData
    """
    
    # Update your player data to reflect the invalidation.
    # FYI, the player's piece is removed from the board,
    # but not its walls.
    
    # When you are working on part 4, there is a small chance you'd
    # want to change your strategy when a player is kicked out.
    playerData.numPlayers -= 1
    playerData.playerLocations[playerId-1]=[-1,-1]
    return playerData